home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
kernel
/
proc
/
procEnviron.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-18
|
25KB
|
973 lines
/*
* procEnviron.c --
*
* Routines to manage a process's environment. The routines in
* this file manage a monitor for the environments.
*
* Copyright 1986, 1988 Regents of the University of California
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies. The University of California
* makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#ifndef lint
static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/proc/procEnviron.c,v 9.2 90/09/12 13:58:02 jhh Exp $ SPRITE (Berkeley)";
#endif /* not lint */
#include <sprite.h>
#include <proc.h>
#include <procInt.h>
#include <sync.h>
#include <sched.h>
#include <sys.h>
#include <stdlib.h>
#include <status.h>
#include <vm.h>
#include <bstring.h>
#include <string.h>
#include <stdio.h>
/*
* The minimum size of the environment that is allocated. This size
* represents the number of environment variables.
*/
#define MIN_ENVIRON_SIZE 5
/*
* Structure to describe an internal version of an environment variable.
*/
typedef struct ProcEnvironVar {
char *name;
int nameLength;
char *value;
int valueLength;
} ProcEnvironVar;
/*
* Monitor declarations.
*/
static Sync_Lock environMonitorLock =
Sync_LockInitStatic("Proc:environMonitorLock");
#define LOCKPTR &environMonitorLock
static void DoCopyEnviron _ARGS_((int srcSize,
ProcEnvironVar *srcVarPtr, int destSize,
ProcEnvironVar *destVarPtr));
static void FreeEnviron _ARGS_((register Proc_EnvironInfo *environPtr,
int size, Boolean freeEnvironInfo));
static ProcEnvironVar *FindVar _ARGS_((Proc_EnvironInfo *environPtr,
char *name));
static ProcEnvironVar *InitializeVar _ARGS_((Proc_EnvironInfo
*environPtr, char *name, int nameLength));
static void DecEnvironRefCount _ARGS_((Proc_EnvironInfo *environPtr));
/*
* ----------------------------------------------------------------------------
*
* Proc_InitMainEnviron --
*
* Allocate an environment for the main process. This sets things up
* so that we don't have to worry about NIL environments.
*
* Results:
* None.
*
* Side effects:
* Environment allocated for main process.
*
* ----------------------------------------------------------------------------
*/
ENTRY void
ProcInitMainEnviron(procPtr)
register Proc_ControlBlock *procPtr; /* Pointer to main's
* PCB. */
{
int i;
LOCK_MONITOR;
procPtr->environPtr =
(Proc_EnvironInfo *) malloc(sizeof(Proc_EnvironInfo));
procPtr->environPtr->refCount = 1;
procPtr->environPtr->size = MIN_ENVIRON_SIZE;
procPtr->environPtr->varArray = (ProcEnvironVar *)
malloc(sizeof(ProcEnvironVar) * MIN_ENVIRON_SIZE);
for (i = 0; i < MIN_ENVIRON_SIZE; i++) {
procPtr->environPtr->varArray[i].name = (char *) NIL;
procPtr->environPtr->varArray[i].value = (char *) NIL;
}
UNLOCK_MONITOR;
}
/*
* ----------------------------------------------------------------------------
*
* Proc_SetupEnviron --
*
* Give this process a pointer to the parents environment and increment
* the reference count.
*
* Results:
* None.
*
* Side effects:
* environPtr field of process is set and reference count incremented
* in the environment.
*
* ----------------------------------------------------------------------------
*/
ENTRY void
ProcSetupEnviron(procPtr)
register Proc_ControlBlock *procPtr; /* Process to setup
* environment for. */
{
Proc_ControlBlock *parentProc;
LOCK_MONITOR;
parentProc = Proc_GetPCB(procPtr->parentID);
procPtr->environPtr = parentProc->environPtr;
procPtr->environPtr->refCount++;
UNLOCK_MONITOR;
}
/*
* ----------------------------------------------------------------------------
*
* DoCopyEnviron --
*
* Copy the source environment into the destination. It is assumed that
* the destination is at least as big as the source. Any remaining
* variables in the destination environment are set to NIL.
*
* Results:
* None.
*
* Side effects:
* Destination gets copy of source environment with any left over
* entries in the destination set to NIL.
*
* ----------------------------------------------------------------------------
*/
INTERNAL static void
DoCopyEnviron(srcSize, srcVarPtr, destSize, destVarPtr)
int srcSize; /* # of variables in
* source environ. */
register ProcEnvironVar *srcVarPtr; /* Pointer to source
* environ variables.*/
int destSize; /* # of variables in
* dest environment. */
register ProcEnvironVar *destVarPtr; /* Pointer to dest
* environ variables. */
{
int i;
for (i = 0; i < srcSize; srcVarPtr++, destVarPtr++, i++) {
if (srcVarPtr->name != (char *) NIL) {
destVarPtr->name = (char *) malloc(srcVarPtr->nameLength + 1);
destVarPtr->nameLength = srcVarPtr->nameLength;
destVarPtr->value = (char *) malloc(srcVarPtr->valueLength + 1);
destVarPtr->valueLength = srcVarPtr->valueLength;
bcopy((Address) srcVarPtr->name, (Address) destVarPtr->name,
srcVarPtr->nameLength + 1);
bcopy((Address) srcVarPtr->value, (Address) destVarPtr->value,
srcVarPtr->valueLength + 1);
} else {
destVarPtr->name = (char *) NIL;
destVarPtr->value = (char *) NIL;
}
}
for (; i < destSize; i++, destVarPtr++) {
destVarPtr->name = (char *) NIL;
destVarPtr->value = (char *) NIL;
}
}
/*
* ----------------------------------------------------------------------------
*
* FreeEnviron --
*
* Free up all allocated memory in the environment. The environment
* structure itself is not freed up unless the free flag is set.
* The actual number of variables in the environment to free up is given.
* This allows the caller to free up an environment that has not
* been totally initialized.
*
* Results:
* None.
*
* Side effects:
* All memory allocated for the given environment is freed.
*
* ----------------------------------------------------------------------------
*/
INTERNAL static void
FreeEnviron(environPtr, size, freeEnvironInfo)
register Proc_EnvironInfo *environPtr; /* Environment
* to free. */
int size; /* Number of variables
* in the environ. */
Boolean freeEnvironInfo;/* TRUE if should free
* environ struct .*/
{
int i;
register ProcEnvironVar *varPtr;
for (i = 0, varPtr = environPtr->varArray; i < size; varPtr++, i++) {
if (varPtr->name != (char *) NIL) {
free((Address) varPtr->name);
free((Address) varPtr->value);
}
}
free((Address) environPtr->varArray);
if (freeEnvironInfo) {
free((Address) environPtr);
}
}
/*
* ----------------------------------------------------------------------------
*
* FindVar --
*
* Search the given environment for a variable with the given name.
* This assumes that the given name is null terminated.
*
* Results:
* A pointer to the environment variable if found, NULL otherwise.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
INTERNAL static ProcEnvironVar *
FindVar(environPtr, name)
Proc_EnvironInfo *environPtr; /* Environment to search. */
char *name; /* Name to search for. */
{
register ProcEnvironVar *varPtr;
int i;
for (i = 0, varPtr = environPtr->varArray;
i < environPtr->size;
varPtr++, i++) {
if (varPtr->name != (char *) NIL &&
strcmp(varPtr->name, name) == 0) {
return(varPtr);
}
}
return((ProcEnvironVar *) NIL);
}
/*
* ----------------------------------------------------------------------------
*
* InitializeVar --
*
* Put the given name for the environment variable into the given
* environment. The environment will be expanded if necessary.
*
* Results:
* A pointer to the initialized environment variable.
*
* Side effects:
* Environment may be expanded.
*
* ----------------------------------------------------------------------------
*/
INTERNAL static ProcEnvironVar *
InitializeVar(environPtr, name, nameLength)
register Proc_EnvironInfo *environPtr; /* Environment to put
* the variable in. */
char *name; /* Name of variable. */
int nameLength; /* Length of null terminated
* name not including null
* character. */
{
register ProcEnvironVar *varPtr;
int i;
int newSize;
for (i = 0, varPtr = environPtr->varArray;
i < environPtr->size;
varPtr++, i++) {
if (varPtr->name == (char *) NIL) {
break;
}
}
/*
* If there was no empty space in the environment then
* make the environment twice as big and set varPtr to point to
* the first null entry in the environment.
*/
if (i == environPtr->size) {
if (environPtr->size == PROC_MAX_ENVIRON_SIZE) {
return((ProcEnvironVar *) NIL);
}
newSize = environPtr->size * 2;
if (newSize > PROC_MAX_ENVIRON_SIZE) {
newSize = PROC_MAX_ENVIRON_SIZE;
}
varPtr = (ProcEnvironVar *)
malloc(sizeof(ProcEnvironVar) * newSize);
DoCopyEnviron(environPtr->size, environPtr->varArray,
newSize, varPtr);
FreeEnviron(environPtr, environPtr->size, FALSE);
environPtr->varArray = varPtr;
varPtr += environPtr->size;
environPtr->size = newSize;
}
/*
* Store the name in the environment variable.
*/
varPtr->name = (char *) malloc(nameLength + 1);
varPtr->nameLength = nameLength;
bcopy((Address) name, (Address) varPtr->name, nameLength + 1);
return(varPtr);
}
/*
* ----------------------------------------------------------------------------
*
* DecEnvironRefCount --
*
* Decrement the reference count on the given environment.
*
* Results:
* None.
*
* Side effects:
* Reference count decremented for the environment.
*
* ----------------------------------------------------------------------------
*/
static INTERNAL void
DecEnvironRefCount(environPtr)
register Proc_EnvironInfo *environPtr;
{
environPtr->refCount--;
if (environPtr->refCount == 0) {
FreeEnviron(environPtr, environPtr->size, TRUE);
}
}
/*
* ----------------------------------------------------------------------------
*
* ProcDecEnvironRefCount --
*
* Decrement the reference count on the given environment.
*
* Results:
* None.
*
* Side effects:
* Reference count decremented for the environment.
*
* ----------------------------------------------------------------------------
*/
ENTRY void
ProcDecEnvironRefCount(environPtr)
register Proc_EnvironInfo *environPtr;
{
LOCK_MONITOR;
DecEnvironRefCount(environPtr);
UNLOCK_MONITOR;
}
/*
* ----------------------------------------------------------------------------
*
* Proc_SetEnvironStub --
*
* Add the given environment variable to the current process's
* environment.
*
* Results:
* Return SYS_ARG_NOACCESS if the name or value are inaccessible.
*
* Side effects:
* The enviroment of the current process is modified.
*
* ----------------------------------------------------------------------------
*/
ENTRY ReturnStatus
Proc_SetEnvironStub(environVar)
Proc_EnvironVar environVar; /* Variable to add to environment. */
{
register ProcEnvironVar *varPtr;
register Proc_ControlBlock *procPtr;
char *namePtr;
char *valuePtr;
int nameLength;
int valueLength;
int nameAccLength;
int valueAccLength;
ReturnStatus status;
LOCK_MONITOR;
procPtr = Proc_GetEffectiveProc();
/*
* Make variable name accessible.
*/
namePtr = environVar.name;
status = Proc_MakeStringAccessible(PROC_MAX_ENVIRON_NAME_LENGTH,
&namePtr, &nameAccLength, &nameLength);
if (status != SUCCESS) {
UNLOCK_MONITOR;
return(status);
}
/*
* Make variable value accessible.
*/
valuePtr = environVar.value;
status = Proc_MakeStringAccessible(PROC_MAX_ENVIRON_VALUE_LENGTH,
&valuePtr, &valueAccLength,
&valueLength);
if (status != SUCCESS) {
Proc_MakeUnaccessible((Address) namePtr, nameAccLength);
UNLOCK_MONITOR;
return(status);
}
/*
* See if the variable already exists. If not then put it in the
* environment.
*/
varPtr = FindVar(procPtr->environPtr, namePtr);
if (varPtr == (ProcEnvironVar *) NIL) {
varPtr = InitializeVar(procPtr->environPtr, namePtr, nameLength);
if (varPtr == (ProcEnvironVar *) NIL) {
Proc_MakeUnaccessible((Address) namePtr, nameAccLength);
Proc_MakeUnaccessible((Address) valuePtr, valueAccLength);
UNLOCK_MONITOR;
return(PROC_ENVIRON_FULL);
}
}
Proc_MakeUnaccessible((Address) namePtr, nameAccLength);
/*
* Put the value of the variable into the environment.
*/
varPtr->value = (char *) malloc(valueLength + 1);
varPtr->valueLength = valueLength;
bcopy((Address) valuePtr, (Address) varPtr->value, valueLength + 1);
Proc_MakeUnaccessible((Address) valuePtr, valueAccLength);
UNLOCK_MONITOR;
return(SUCCESS);
}
/*
* ----------------------------------------------------------------------------
*
* Proc_UnsetEnvironStub --
*
* Remove the given environment variable from the current process's
* environment.
*
* Results:
* Return PROC_NOT_SET_ENVIRON_VAR if the variable is not set and
* SYS_ARG_NOACCESS if the name is not accessible.
*
* Side effects:
* The enviroment of the current process is modified.
*
* ----------------------------------------------------------------------------
*/
ENTRY ReturnStatus
Proc_UnsetEnvironStub(environVar)
Proc_EnvironVar environVar; /* Variable to remove. */
{
register ProcEnvironVar *varPtr;
register Proc_ControlBlock *procPtr;
char *namePtr;
int nameLength;
int nameAccLength;
ReturnStatus status;
LOCK_MONITOR;
procPtr = Proc_GetEffectiveProc();
/*
* Make variable name accessible.
*/
namePtr = environVar.name;
status = Proc_MakeStringAccessible(PROC_MAX_ENVIRON_NAME_LENGTH,
&namePtr, &nameAccLength,
&nameLength);
if (status != SUCCESS) {
UNLOCK_MONITOR;
return(status);
}
/*
* Find the variable in the environment.
*/
varPtr = FindVar(procPtr->environPtr, namePtr);
Proc_MakeUnaccessible((Address) namePtr, nameAccLength);
if (varPtr == (ProcEnvironVar *) NIL) {
UNLOCK_MONITOR;
return(PROC_NOT_SET_ENVIRON_VAR);
}
/*
* Unset the variable by freeing up the space that was allocated
* for it.
*/
free((Address) varPtr->name);
varPtr->name = (char *) NIL;
free((Address) varPtr->value);
varPtr->value = (char *) NIL;
UNLOCK_MONITOR;
return(SUCCESS);
}
/*
* ----------------------------------------------------------------------------
*
* Proc_GetEnvironVarStub --
*
* Return the value of the given environment variable in the current
* process's environment.
*
* Results:
* SYS_ARG_NOACCESS if place to store value is a bad address or
* PROC_NOT_SET_ENVIRON_VAR if the environment variable doesn't
* exist.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
ReturnStatus
Proc_GetEnvironVarStub(environVar)
Proc_EnvironVar environVar; /* Variable to retrieve. */
{
register ProcEnvironVar *varPtr;
register Proc_ControlBlock *procPtr;
char *namePtr;
int nameLength;
int nameAccLength;
ReturnStatus status;
LOCK_MONITOR;
procPtr = Proc_GetEffectiveProc();
/*
* Make name accessible.
*/
namePtr = environVar.name;
status = Proc_MakeStringAccessible(PROC_MAX_ENVIRON_NAME_LENGTH,
&namePtr, &nameAccLength, &nameLength);
if (status != SUCCESS) {
UNLOCK_MONITOR;
return(status);
}
/*
* Find the variable. If not found then return an error.
*/
varPtr = FindVar(procPtr->environPtr, namePtr);
Proc_MakeUnaccessible((Address) namePtr, nameAccLength);
if (varPtr == (ProcEnvironVar *) NIL) {
UNLOCK_MONITOR;
return(PROC_NOT_SET_ENVIRON_VAR);
}
/*
* Copy out the value of the variable.
*/
if (Proc_ByteCopy(FALSE, varPtr->valueLength + 1, (Address) varPtr->value,
(Address) environVar.value) != SUCCESS) {
UNLOCK_MONITOR;
return(SYS_ARG_NOACCESS);
}
UNLOCK_MONITOR;
return(SUCCESS);
}
/*
* ----------------------------------------------------------------------------
*
* Proc_GetEnvironRangeStub --
*
* Return as many environment variables as possible in the given range.
* Variables are numbered from 0. The actual number of environment
* variables returned is returned in numActualVarsPtr. The null
* string is returned for any environment variables that are not set.
*
* Results:
* Error status if some error occcurs. SUCCESS otherwise.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
ENTRY ReturnStatus
Proc_GetEnvironRangeStub(first, last, envArray, numActualVarsPtr)
int first; /* First var to
* retrieve. */
int last; /* Last var to
* retrieve. */
register Proc_EnvironVar *envArray; /* Where to
* store vars.*/
int *numActualVarsPtr; /* Number of vars
* retrieved. */
{
Proc_EnvironVar *saveEnvPtr;
register ProcEnvironVar *varPtr;
register Proc_ControlBlock *procPtr;
ReturnStatus status = SUCCESS;
int i;
int numBytes;
int numVars;
char nullChar = '\0';
LOCK_MONITOR;
if (last < first || first < 0) {
UNLOCK_MONITOR;
return(SYS_INVALID_ARG);
}
procPtr = Proc_GetEffectiveProc();
if (first >= procPtr->environPtr->size) {
numVars = 0;
status = Vm_CopyOut(sizeof(numVars),
(Address) &numVars, (Address) numActualVarsPtr);
if (status != SUCCESS) {
status = SYS_ARG_NOACCESS;
}
UNLOCK_MONITOR;
return(status);
}
if (last >= procPtr->environPtr->size) {
last = procPtr->environPtr->size - 1;
}
/*
* Make the environment array accessible.
*/
i = (last - first + 1) * sizeof(Proc_EnvironVar);
Vm_MakeAccessible(VM_READONLY_ACCESS, i,
(Address) envArray, &numBytes, (Address *) &saveEnvPtr);
envArray = saveEnvPtr;
if (numBytes != i) {
if (envArray != (Proc_EnvironVar *) NIL) {
Vm_MakeUnaccessible((Address) envArray, numBytes);
}
UNLOCK_MONITOR;
return(SYS_ARG_NOACCESS);
}
/*
* Copy out the environment variables.
*/
for (i = first, varPtr = &(procPtr->environPtr->varArray[first]);
i <= last;
i++, varPtr++, envArray++) {
if (varPtr->name == (char *) NIL) {
if (Vm_CopyOut(1, (Address) &nullChar,
(Address) envArray->name) != SUCCESS) {
status = SYS_ARG_NOACCESS;
break;
} else {
continue;
}
}
if (Vm_CopyOut(varPtr->nameLength + 1, (Address) varPtr->name,
(Address) envArray->name) != SUCCESS) {
status = SYS_ARG_NOACCESS;
break;
}
if (Vm_CopyOut(varPtr->valueLength + 1, (Address) varPtr->value,
(Address) envArray->value) != SUCCESS) {
status = SYS_ARG_NOACCESS;
break;
}
}
Vm_MakeUnaccessible((Address) saveEnvPtr, numBytes);
if (status == SUCCESS) {
numVars = last - first + 1;
if (Vm_CopyOut(sizeof(numVars), (Address) &numVars,
(Address) numActualVarsPtr) != SUCCESS) {
status = SYS_ARG_NOACCESS;
}
}
UNLOCK_MONITOR;
return(status);
}
/*
* ----------------------------------------------------------------------------
*
* Proc_CopyEnvironStub --
*
* Give the current process its own copy of the environment.
*
* Results:
* Always returns SUCCESS.
*
* Side effects:
* New environment allocated.
*
* ----------------------------------------------------------------------------
*/
ENTRY ReturnStatus
Proc_CopyEnvironStub()
{
register Proc_EnvironInfo *newEnvironPtr;
register Proc_ControlBlock *procPtr;
LOCK_MONITOR;
procPtr = Proc_GetEffectiveProc();
if (procPtr->environPtr->refCount == 1) {
UNLOCK_MONITOR;
return(SUCCESS);
}
newEnvironPtr = (Proc_EnvironInfo *) malloc(sizeof(Proc_EnvironInfo));
newEnvironPtr->refCount = 1;
newEnvironPtr->size = procPtr->environPtr->size;
newEnvironPtr->varArray = (ProcEnvironVar *)
malloc(sizeof(ProcEnvironVar) * newEnvironPtr->size);
DoCopyEnviron(newEnvironPtr->size, procPtr->environPtr->varArray,
newEnvironPtr->size, newEnvironPtr->varArray);
DecEnvironRefCount(procPtr->environPtr);
procPtr->environPtr = newEnvironPtr;
UNLOCK_MONITOR;
return(SUCCESS);
}
/*
* ----------------------------------------------------------------------------
*
* Proc_InstallEnvironStub --
*
* Install the given environment as the environment of the current
* process.
*
* Results:
* Error if args invalid or inaccessible. SUCCESS otherwise.
*
* Side effects:
* A new enviroment is allocated.
*
* ----------------------------------------------------------------------------
*/
ENTRY ReturnStatus
Proc_InstallEnvironStub(environ, numVars)
Proc_EnvironVar environ[]; /* Environment to install. */
int numVars; /* Number of variables in the
* environment. */
{
register Proc_EnvironVar *userEnvironPtr;
register Proc_EnvironInfo *newEnvironPtr;
register ProcEnvironVar *varPtr;
Proc_EnvironVar *saveEnvironPtr;
int environLength;
int i;
int nameAccLength;
int nameLength;
char *namePtr;
int valueAccLength;
int valueLength;
char *valuePtr;
ReturnStatus status;
Proc_ControlBlock *procPtr;
LOCK_MONITOR;
if (numVars > PROC_MAX_ENVIRON_SIZE) {
UNLOCK_MONITOR;
return(SYS_INVALID_ARG);
}
/*
* Make the users environment array accessible.
*/
userEnvironPtr = (Proc_EnvironVar *) NIL;
if (numVars > 0) {
Vm_MakeAccessible(VM_READONLY_ACCESS, numVars * sizeof(Proc_EnvironVar),
(Address) environ, &environLength,
(Address *) &saveEnvironPtr);
userEnvironPtr = saveEnvironPtr;
if (environLength != numVars * sizeof(Proc_EnvironVar)) {
if (userEnvironPtr != (Proc_EnvironVar *) NIL) {
Vm_MakeUnaccessible((Address) userEnvironPtr, environLength);
}
UNLOCK_MONITOR;
return(SYS_ARG_NOACCESS);
}
}
/*
* Allocate a new environment of size at least MIN_ENVIRON_SIZE.
*/
newEnvironPtr = (Proc_EnvironInfo *) malloc(sizeof(Proc_EnvironInfo));
newEnvironPtr->refCount = 1;
if (numVars < MIN_ENVIRON_SIZE) {
newEnvironPtr->size = MIN_ENVIRON_SIZE;
} else {
newEnvironPtr->size = numVars;
}
newEnvironPtr->varArray = (ProcEnvironVar *)
malloc(sizeof(ProcEnvironVar) * newEnvironPtr->size);
/*
* Read in the users environment variables and store them in the
* new environment.
*/
for (i = 0, varPtr = newEnvironPtr->varArray;
i < numVars;
userEnvironPtr++, varPtr++, i++) {
if (userEnvironPtr->name != (char *) USER_NIL) {
namePtr = userEnvironPtr->name;
status = Proc_MakeStringAccessible(PROC_MAX_ENVIRON_NAME_LENGTH,
&namePtr, &nameAccLength, &nameLength);
if (status != SUCCESS) {
Vm_MakeUnaccessible((Address) saveEnvironPtr, environLength);
FreeEnviron(newEnvironPtr, i - 1, TRUE);
UNLOCK_MONITOR;
return(SYS_ARG_NOACCESS);
}
valuePtr = userEnvironPtr->value;
status = Proc_MakeStringAccessible(PROC_MAX_ENVIRON_VALUE_LENGTH,
&valuePtr, &valueAccLength, &valueLength);
if (status != SUCCESS) {
Vm_MakeUnaccessible((Address) saveEnvironPtr, environLength);
Proc_MakeUnaccessible((Address) namePtr, nameAccLength);
FreeEnviron(newEnvironPtr, i - 1, TRUE);
UNLOCK_MONITOR;
return(SYS_ARG_NOACCESS);
}
varPtr->name = (char *) malloc(nameLength + 1);
varPtr->nameLength = nameLength;
bcopy(namePtr, varPtr->name, nameLength + 1);
varPtr->value = (char *) malloc(valueLength + 1);
varPtr->valueLength = valueLength;
bcopy(valuePtr, varPtr->value, valueLength + 1);
Proc_MakeUnaccessible((Address) namePtr, nameAccLength);
Proc_MakeUnaccessible((Address) valuePtr, valueAccLength);
} else {
varPtr->name = (char *) NIL;
varPtr->value = (char *) NIL;
}
}
if (numVars > 0) {
Vm_MakeUnaccessible((Address) saveEnvironPtr, environLength);
}
/*
* If we allocated more than the user requested then set the excess
* variables to NIL.
*/
for (; i < newEnvironPtr->size; i++, varPtr++) {
varPtr->name = (char *) NIL;
varPtr->value = (char *) NIL;
}
/*
* Make this new environment the environment of the current process.
*/
procPtr = Proc_GetEffectiveProc();
DecEnvironRefCount(procPtr->environPtr);
procPtr->environPtr = newEnvironPtr;
UNLOCK_MONITOR;
return(SUCCESS);
}